(function($, undefined) {

$.widget('ui.aywScrollable', {
	options: {
		activeClass: 'active',
		clonedClass: 'cloned',
		disabledClass: 'disabled',
		easing: 'swing',
		index: 0,
		item: '> *',
		items: 'ul',
		keyboard: true,
		mousewheel: false,
		next: '.next',
		prev: '.prev',
		size: 1,
		speed: 400,
		vertical: false,
		touch: true,
		wheelSpeed: 0
	},

	_create: function() {
		var o = this.options;

		this.index = 0;
		this.itemWrap = this.element.children();
		this.itemWrap = this.element.find(o.items);
		this.prevBtn = this.element.find(o.prev);
		this.nextBtn = this.element.find(o.next);

		this._bindEvents();
		this._initItemWrap();
		this._initPrevNext();
		this._initSeek();
	},

	_bindEvents: function() {
		var self = this,
			o = this.options,
			prefix = this.widgetName.toLowerCase();

		this.element
			.bind(prefix + 'seek.' + this.widgetName, function(e, i, time) {
				i += 1;
				self.prevBtn.toggleClass(o.disabledClass, i <= o.size);
				self.nextBtn.toggleClass(o.disabledClass, Math.ceil(i / o.size) >= Math.ceil(self.getSize() / o.size));
				e.stopPropagation();
			});
	},

	_initItemWrap: function() {
		var o = this.options,
			props = {
				'position': 'relative'
			};

		if (!o.vertical) {
			props.width = '20000px';
		} else {
			props.height = '20000px';
		}

		this.itemWrap.css(props);
	},

	_initPrevNext: function() {
		var self = this;

		this.prevBtn
			.bind('click.' + self.widgetName, function(e) {
				self.prev();
				return false;
			});

		this.nextBtn
			.bind('click.' + self.widgetName, function(e) {
				self.next();
				return false;
			});
	},

	_initSeek: function() {
		var o = this.options,
			$hide, $items,
			index, i, len,
			d = [];

		index = o.index;
		if (typeof index === 'string' && isNaN(index * 1)) {
			$items = this.getItems();
			index = $items.filter(index).eq(0);
			index = $items.index(index);
		}

		$hide = this.itemWrap
			.parents()
			.andSelf()
			.filter(function () {
				if ($(this).css('display') === 'none') {
					d.push(this.style.display);
					return true;
				}
			});

		if ($hide.length) {
			$hide.css({'display': 'block'});
			this.seekTo(index, 0);
			for (i = 0, len = d.length; i < len; i++) {
				$hide[i].style.display = d[i];
			}
		} else {
			this.seekTo(index, 0);
		}
	},

	getIndex: function() {
		return this.index;
	},

	getItems: function() {
		return this.itemWrap.find(this.options.item);
	},

	getSize: function() {
		return this.getItems().size();
	},

	move: function(offset, time) {
		return this.seekTo(this.index + offset, time);
	},

	next: function(time) {
		return this.move(this.options.size, time);
	},

	prev: function(time) {
		return this.move(-this.options.size, time);
	},

	begin: function(time) {
		return this.seekTo(0, time);
	},

	end: function(time) {
		return this.seekTo(this.getSize() - 1, time);
	},

	seekTo: function(i, time) {
		var self = this,
			o = this.options,
			item, props;

		// ensure numeric index
		if (i.jquery) {
			i = this.getItems().index(i);
		} else {
			i *= 1;
		}

		if (i < 0 || isNaN(i)) {
			i = 0;
		} else if (i > this.getSize() - 1) {
			i = this.getSize() - 1;
		}

		if (!this._trigger('beforSeek', undefined, [i, time])) {
			return;
		}

		this.index = i;
		item = this.getItems().eq(i - i % o.size);
		props = o.vertical ? {top: -item.position().top} : {left: -item.position().left};
		time = (time === undefined) ? o.speed : time;

		this.itemWrap.animate(props, time, o.easing, function() {
			self._trigger('seek', undefined, [i, time]);
		});
	},
	
	addItem: function(item) {
		var $item = $(item);

		this.itemWrap
			.append($item);

		this.seekTo($item);
	}
});

})(jQuery);